#pragma once
#include "glm/glm.hpp"
using namespace glm;
#include <string>
#include <map>
#include <vector>
using namespace std;
#include "lodepng.h"

#include "Scene.h"
#include "ShaderCollection.h"
#include "DiffuseShader.h"
#include "SpecularShader.h"
#include "ReflectiveShader.h"
#include "RefractiveShader.h"
#include "SurfaceShader.h"
#include "Shape.h"
#include "Plane.h"
#include "Sphere.h"
#include "Triangle.h"
#include "Box.h"
#include "Light.h"
#include "Renderer.h"
#include "ImageBuffer.h"
#include "OBJLoader.h"
#include "Stats.h"

class SceneManager
{
public:
	SceneManager();
	~SceneManager();

	//Scene functions
	void addPlane(vec3 _pos, vec3 _rot, vec3 _up, string _shaderName);
	void addSphere(vec3 _pos, vec3 _rot, float _rad, string _shaderName);
	void addTriangle(vec3 _pos, vec3 _rot, vec3 _pt1, vec3 _pt2, vec3 _pt3, vec3 _rotation, string _shaderName);
	void addBox(vec3 _pos, vec3 _rot, vec3 _min, vec3 _max, vec3 _rotation, string _shaderName);
	void addOBJ(vec3 _pos, string _path, vec3 _rotation, string _shaderName);
	void addLight(vec3 _pos, vec4 _col, float _instense);
	void addCamera(vec3 _pos, vec3 _target, vec3 _up, float _fov, int _width, int _height);
	void clear();	//clears out the geometry, lights, and cameras

	//Renderer functions
	void AAmode(int _mode){ render->AAmode(_mode); }
	void AAsamples(int _samples){ render->AAsamples(_samples); }
	void AAsamplePattern(int _mode){ render->AAsamplePattern(_mode); }
	void AAminSamples(int _samples){ render->AAminSamples(_samples); }
	void AAmaxSamples(int _samples){ render->AAmaxSamples(_samples); }
	void maxBounces(int _b){ render->maxBounces(_b); }
	void scene(Scene* _sc){ delete theScene; theScene = _sc; render->scene(_sc); }
	void camera(Camera* _cam){ render->camera(_cam); }
	void setActiveCameraToLatest();
	void backgroundColor(vec4 _col){ render->backgroundColor(_col); }
	void clampMode(bool _c){ render->clampMode(_c); }
	void imgSize(int _w, int _h, int _layers);
	void imgLayers(int _layers);
	void startRender();

	//Shader functions
	void startShaderCollection(string _name);	//begin building a shaderCollection
	void addDiffuseShader(float _amount, vec4 _col);
	void addSpecularShader(float _amount, vec4 _col, float _shine);
	void addReflectiveShader(float _amount, vec4 _col);
	void addRefractiveShader(float _amount, float _IOR);
	void endShaderCollection();					//link all previous subshaders to the current shaderCollection

	ImageBuffer* getImg(){ return render->image(); }
	Renderer* getRender(){ return render; }

	void saveLayerToFile(string _path, int _layer);

private:
	string curShader;
	bool buildingShader = false;

	Scene* theScene;
	Renderer* render;
	//ImageBuffer* image;
	map<string, ShaderCollection*> theShaders;
};

